import pygame
from pygame.locals import *
try:
    import android
except ImportError:
    android = None
from pgu import gui
import pickle
from math import floor,sqrt

from constants import *

class DoneDialog(gui.Dialog):
    def __init__(self, title, main):
        gui.Dialog.__init__(self, title, main)
        self.done = False
        
    def close(self, w=None):
        self.done = True
        gui.Dialog.close(self,w)

class Chooser(gui.Dialog):
    def __init__(self, title, texts):
        table = gui.Table()
        for i in range(len(texts)):
            button = gui.Button(texts[i],height=80,width=270,font=d.quitebig_font)
            button.connect(gui.CLICK, self.set, i)
            table.td(button)
            table.tr()
            table.td(gui.Spacer(height=3,width=280))
            table.tr()
        contents = gui.ScrollArea(table,350,650,hscrollbar=False)        
        gui.Dialog.__init__(self, gui.Label(title), contents)
        self.done = False
        self.texts = texts
        self.index_chosen = None

    def set(self, i):
        self.index_chosen = i
        self.close()

    def close(self, w=None):
        self.done = True
        gui.Dialog.close(self,w)
        
class ContainerInfoDialog(gui.Dialog):
    def __init__(self,label_text,contents):
        gui.Dialog.__init__(self,gui.Label(label_text),gui.ScrollArea(contents,350,650,hscrollbar=False))
        self.done = False
        
    def close(self, w=None):
        self.done = True
        gui.Dialog.close(self,w)        
        
class Display:
    def __init__(self):
        pass

    def initialize(self):
        pygame.init()
        if android:
            android.init()
            android.map_key(android.KEYCODE_BACK, pygame.K_ESCAPE)            
            self.screensize = (480,800)
        else:
            self.screensize = (480,800)
        self.screen = pygame.display.set_mode(self.screensize)
        self.screen.fill((0,0,0))
        pygame.display.flip()
        self.background = pygame.image.load('files/background.jpg').convert_alpha()
        self.message_pane = pygame.Surface([self.screensize[0]-25,10000])
        self.images = {} # I_ code to pic
        self.greened_big_images = {}
        self.darkened_big_images = {}
        self.whiteout_big_images = {}          
        portraits = {I_PRIEST_1:'priest_1', I_ROGUE_1:'rogue_1', I_WARRIOR_1:'warrior_1', I_MAGE_1:'wizard_1', I_PRIEST_2:'priest_2', I_ROGUE_2:'rogue_2', I_WARRIOR_2:'warrior_2', I_MAGE_2:'wizard_2', I_PRIEST_3:'priest_3', I_ROGUE_3:'rogue_3', I_WARRIOR_3:'warrior_3', I_MAGE_3:'wizard_3'}
        for i_code in portraits.keys():
            self.images[i_code] = pygame.image.load('files/' + portraits[i_code] + '.png').convert_alpha()
            self.greened_big_images[i_code] = pygame.image.load('files/' + portraits[i_code] + '_green.png').convert_alpha()
            self.darkened_big_images[i_code] = pygame.image.load('files/' + portraits[i_code] + '_dark.png').convert_alpha()
            self.whiteout_big_images[i_code] = pygame.image.load('files/' + portraits[i_code] + '_white.png').convert_alpha()
        self.images[I_ARTIFICER] = pygame.image.load('files/artificer.png').convert_alpha()
        self.images[I_BAN_SIDHE] = pygame.image.load('files/ban_sidhe.png').convert_alpha()
        self.images[I_BASIC_TROGLODYTE] = pygame.image.load('files/basic_troglodyte.png').convert_alpha()
        self.images[I_BASILISK] = pygame.image.load('files/basilisk.png').convert_alpha()
        self.images[I_BEASTMASTER] = pygame.image.load('files/beastmaster.png').convert_alpha()
        self.images[I_BLACK_KNIGHT] = pygame.image.load('files/black_knight.png').convert_alpha()
        self.images[I_BLUE_DRAGON] = pygame.image.load('files/blue_dragon.png').convert_alpha()
        self.images[I_BURNING_GHOST] = pygame.image.load('files/burning_ghost.png').convert_alpha()
        self.images[I_CENTIPEDE] = pygame.image.load('files/centipede.png').convert_alpha()
        self.images[I_CLAWED_DEMON] = pygame.image.load('files/clawed_demon.png').convert_alpha()
        self.images[I_CLAY_GOLEM] = pygame.image.load('files/clay_golem.png').convert_alpha()
        self.images[I_COBRA] = pygame.image.load('files/cobra.png').convert_alpha()
        self.images[I_DARK_DWARF] = pygame.image.load('files/dark_dwarf.png').convert_alpha()
        self.images[I_DARK_ELF_BOSS] = pygame.image.load('files/dark_elf_boss.png').convert_alpha()
        self.images[I_DARK_PRIEST] = pygame.image.load('files/dark_priest.png').convert_alpha()
        self.images[I_DRAGON] = pygame.image.load('files/dragon.png').convert_alpha()
        self.images[I_EYE] = pygame.image.load('files/eye.png').convert_alpha()
        self.images[I_FIRE_ELEMENTAL] = pygame.image.load('files/fire_elemental.png').convert_alpha()
        self.images[I_FIREFLY] = pygame.image.load('files/firefly.png').convert_alpha()
        self.images[I_GREEN_DRAGON] = pygame.image.load('files/green_dragon.png').convert_alpha()
        self.images[I_HARPY] = pygame.image.load('files/harpy.png').convert_alpha()
        self.images[I_JELLY] = pygame.image.load('files/jelly.png').convert_alpha()
        self.images[I_KOBOLD] = pygame.image.load('files/kobold.png').convert_alpha()
        self.images[I_LIME_JELLY] = pygame.image.load('files/lime_jelly.png').convert_alpha()
        self.images[I_MAGE] = pygame.image.load('files/mage.png').convert_alpha()
        self.images[I_MILLIPEDE] = pygame.image.load('files/millipede.png').convert_alpha()
        self.images[I_MUTE_GHOST] = pygame.image.load('files/mute_ghost.png').convert_alpha()
        self.images[I_NAGA] = pygame.image.load('files/naga.png').convert_alpha()
        self.images[I_NAGA2] = pygame.image.load('files/naga2.png').convert_alpha()
        self.images[I_OOZE] = pygame.image.load('files/ooze.png').convert_alpha()
        self.images[I_ORC] = pygame.image.load('files/orc.png').convert_alpha()
        self.images[I_ORC_CHAMPION] = pygame.image.load('files/orc_champion.png').convert_alpha()
        self.images[I_ORC_PEON] = pygame.image.load('files/orc_peon.png').convert_alpha()
        self.images[I_PYTHON] = pygame.image.load('files/python.png').convert_alpha()
        self.images[I_SHADOW] = pygame.image.load('files/shadow.png').convert_alpha()
        self.images[I_SKELETON_MOB] = pygame.image.load('files/skeleton_mob.png').convert_alpha()
        self.images[I_SNAKE] = pygame.image.load('files/snake.png').convert_alpha()
        self.images[I_SORCERER] = pygame.image.load('files/sorcerer.png').convert_alpha()
        self.images[I_SORCERER_WHITE] = pygame.image.load('files/sorcerer_white.png').convert_alpha()
        self.images[I_SPECTRE] = pygame.image.load('files/spectre.png').convert_alpha()
        self.images[I_STONE_GOLEM] = pygame.image.load('files/stone_golem.png').convert_alpha()
        self.images[I_SUMMONER] = pygame.image.load('files/summoner.png').convert_alpha()
        self.images[I_TROGLODYTE] = pygame.image.load('files/troglodyte.png').convert_alpha()
        self.images[I_TROGLODYTE_PRIEST] = pygame.image.load('files/troglodyte_priest.png').convert_alpha()
        self.images[I_TROGLODYTE_SHAMAN] = pygame.image.load('files/troglodyte_shaman.png').convert_alpha()
        self.images[I_UNDEAD_BOSS] = pygame.image.load('files/undead_boss.png').convert_alpha()
        self.images[I_UNDEAD_BOSS_WHITE] = pygame.image.load('files/undead_boss_white.png').convert_alpha()
        self.images[I_WASP] = pygame.image.load('files/wasp.png').convert_alpha()
        self.images[I_WHITE_WOLF] = pygame.image.load('files/white_wolf.png').convert_alpha()
        self.images[I_WIGHT] = pygame.image.load('files/wight.png').convert_alpha()
        self.images[I_WOLF] = pygame.image.load('files/wolf.png').convert_alpha()
        self.images[I_WRAITH] = pygame.image.load('files/wraith.png').convert_alpha()
        self.images[I_UGLY_THING] = pygame.image.load('files/ugly_thing.png').convert_alpha()
        self.images[I_OGRE] = pygame.image.load('files/ogre.png').convert_alpha()
        self.images[I_BLACK_OGRE] = pygame.image.load('files/black_ogre.png').convert_alpha()
        self.images[I_HILL_GIANT] = pygame.image.load('files/hill_giant.png').convert_alpha()
        self.images[I_ORC_BOSS] = pygame.image.load('files/orc_boss.png').convert_alpha()
        self.images[I_SNAKE_BOSS] = pygame.image.load('files/snake_boss.png').convert_alpha()
        self.images[I_GOLD] = pygame.image.load('files/gold.png').convert_alpha()
        self.images[I_GEMS] = pygame.image.load('files/gems.png').convert_alpha()
        self.images[I_SKELETON] = pygame.image.load('files/skeleton.png').convert_alpha()
        self.images[I_CROWN] = pygame.image.load('files/crown.png').convert_alpha()
        self.images[I_GEMS_CHEST] = pygame.image.load('files/gems_chest.png').convert_alpha()
        self.images[I_GOLD_CHEST] = pygame.image.load('files/gold_chest.png').convert_alpha()
        self.images[I_EXPLOSIVE_RUNE] = pygame.image.load('files/explosive_rune.png').convert_alpha()
        self.images[I_PIT] = pygame.image.load('files/pit.png').convert_alpha()
        self.images[I_FIRE] = pygame.image.load('files/fire.png').convert_alpha()
        self.images[I_LIGHTNING] = pygame.image.load('files/lightning.png').convert_alpha()
        self.images[I_MISSILE] = pygame.image.load('files/missile.png').convert_alpha()
        self.images[I_POISON_CLOUD] = pygame.image.load('files/poison_cloud.png').convert_alpha()
        self.images[I_SPARKLING_CLOUD] = pygame.image.load('files/sparkling_cloud.png').convert_alpha()
        self.images[I_WATER] = pygame.image.load('files/water.png').convert_alpha()
        self.images[I_DISMANTLE] = pygame.image.load('files/dismantle.png').convert_alpha()
        self.images[I_TURTLOID] = pygame.image.load('files/turtloid.png').convert_alpha()
        self.images[I_TURTLOID_INVULNERABLE] = pygame.image.load('files/turtloid_invulnerable.png').convert_alpha()
        self.images[I_DARK_ELF_ARCHER] = pygame.image.load('files/dark_elf_archer.png').convert_alpha()
        self.images[I_ORC_SLAVEMASTER] = pygame.image.load('files/orc_slavemaster.png').convert_alpha()
        self.images[I_ORC_ROCK_THROWER] = pygame.image.load('files/orc_rock_thrower.png').convert_alpha()
        self.images[I_ORC_WITH_MANCATCHER] = pygame.image.load('files/orc_with_mancatcher.png').convert_alpha()
        self.images[I_BLAST_SPORE] = pygame.image.load('files/blast_spore.png').convert_alpha()
        self.images[I_LEPRECHAUN] = pygame.image.load('files/leprechaun.png').convert_alpha()
        self.images[I_ORC_AGITATOR] = pygame.image.load('files/orc_agitator.png').convert_alpha()
        self.images[I_SUMMONING_RUNE] = pygame.image.load('files/summoning_rune.png').convert_alpha()
        self.images[I_SPIKED_PIT] = pygame.image.load('files/spiked_pit.png').convert_alpha()
        self.images[I_GAS_TRAP] = pygame.image.load('files/gas_trap.png').convert_alpha()
        self.images[I_LOOT] = pygame.image.load('files/loot.png').convert_alpha()
        self.images[I_MANTICORE] = pygame.image.load('files/manticore.png').convert_alpha()
        self.images[I_TROLL] = pygame.image.load('files/troll.png').convert_alpha()
        self.images[I_FROZEN_SPIRIT] = pygame.image.load('files/frozen_spirit.png').convert_alpha()
        self.images[I_WARLOCK] = pygame.image.load('files/warlock.png').convert_alpha()
        self.images[I_GIANT_ANT] = pygame.image.load('files/giant_ant.png').convert_alpha()
        self.images[I_THUG] = pygame.image.load('files/thug.png').convert_alpha()
        self.images[I_BIG_KOBOLD] = pygame.image.load('files/big_kobold.png').convert_alpha()
        self.images[I_GOBLIN] = pygame.image.load('files/goblin.png').convert_alpha()
        self.images[I_BEETLE] = pygame.image.load('files/beetle.png').convert_alpha()
        self.images[I_MINOTAUR] = pygame.image.load('files/minotaur.png').convert_alpha()
        self.images[I_SCORPION] = pygame.image.load('files/scorpion.png').convert_alpha()
        self.images[I_BEAR] = pygame.image.load('files/bear.png').convert_alpha()
        self.images[I_YOUNG_NECROMANCER] = pygame.image.load('files/young_necromancer.png').convert_alpha()
        self.images[I_BIG_SPIDER] = pygame.image.load('files/big_spider.png').convert_alpha()
        self.images[I_HELLHOUND] = pygame.image.load('files/hellhound.png').convert_alpha()
        self.images[I_DARK_DWARF_LAIRD] = pygame.image.load('files/dark_dwarf_laird.png').convert_alpha()
        self.images[I_DARK_ELF_DRUID] = pygame.image.load('files/dark_elf_druid.png').convert_alpha()
        self.images[I_MUMMY] = pygame.image.load('files/mummy.png').convert_alpha()
        self.images[I_AIR_ELEMENTAL] = pygame.image.load('files/air_elemental.png').convert_alpha()
        self.images[I_POLTERGEIST] = pygame.image.load('files/poltergeist.png').convert_alpha()
        self.images[I_BERSERKER] = pygame.image.load('files/berserker.png').convert_alpha()
        self.images[I_DOOR] = pygame.image.load('files/door.png').convert_alpha()
        self.images[I_STAIRS] = pygame.image.load('files/stairs.png').convert_alpha()
        self.images[I_RED] = self.make_singlecolor_overlay((255,0,0),60)
        self.images[I_GREEN] = self.make_singlecolor_overlay((0,255,0),60)
        self.images[I_GREY] = self.make_singlecolor_overlay((100,100,100),150)
        self.images[I_PALE] = self.make_singlecolor_overlay((255,255,255),40)
        self.images[I_VERYPALE] = self.make_singlecolor_overlay((255,255,255),80)
        self.images[I_RED_FRAME] = self.make_singlecolor_overlay((0,0,0),255)
        self.images[I_RED_FRAME].set_colorkey((0,0,0))
        pygame.draw.rect(self.images[I_RED_FRAME], (255,0,0), Rect(0,0,96,96), 1)
        self.images[I_GREEN_FRAME] = self.make_singlecolor_overlay((0,0,0),255)
        self.images[I_GREEN_FRAME].set_colorkey((0,0,0))
        pygame.draw.rect(self.images[I_GREEN_FRAME], (0,255,0), Rect(0,0,96,96), 1)
        self.images[I_BLUE_FRAME] = self.make_singlecolor_overlay((0,0,0),255)
        self.images[I_BLUE_FRAME].set_colorkey((0,0,0))
        pygame.draw.rect(self.images[I_BLUE_FRAME], (0,0,255), Rect(0,0,96,96), 1)
        self.big_images = self.images
        self.small_images = {}
        self.images = {}
        for i in self.big_images.keys():
            if self.big_images[i].get_height()==192:
                self.small_images[i] = pygame.transform.scale(self.big_images[i],(40,80))
            else:
                self.small_images[i] = pygame.transform.scale(self.big_images[i],(40,40)) # was (48,48)
            self.images[i] = pygame.transform.scale(self.big_images[i],((self.big_images[i].get_width()*2)/3,(self.big_images[i].get_height()*2)/3))
        self.images[I_SKULL_CROSSBONES] = pygame.image.load('files/skull_crossbones.bmp').convert()
        self.images[I_SKULL_CROSSBONES].set_colorkey((0,0,0))
        self.images[I_PAUSE] = pygame.image.load('files/pause.jpg').convert_alpha()
        self.images[I_QUIT] = pygame.image.load('files/save.jpg').convert_alpha()
        self.images[I_RESTART] = pygame.image.load('files/restart.jpg').convert_alpha()
        self.images[I_FLEE] = pygame.image.load('files/flee.jpg').convert_alpha()
        self.grey_out = False
        self.grey_screen = pygame.Surface(self.screensize)
        self.grey_screen.fill([0,100,100])
        self.grey_screen.set_alpha(180)
        self.blue_screen = pygame.Surface(self.screensize)
        self.blue_screen.fill([0,0,200])
        self.blue_screen.set_alpha(50)
        self.dim_screen = pygame.Surface(self.screensize)
        self.dim_screen.fill([0,0,0])
        self.dim_screen.set_alpha(85)
        self.font = pygame.font.Font("files/FreeSans.ttf", 20)
        self.small_font = pygame.font.Font("files/FreeSans.ttf", 12)
        self.medium_font = pygame.font.Font("files/FreeSans.ttf", 16)
        self.quitebig_font = pygame.font.Font("files/FreeSans.ttf", 24)
        self.big_font = pygame.font.Font("files/FreeSans.ttf", 36)
        self.message_pane_at = (12, 302)
        self.pos_to_corner = {} # POS_C_ or POS_M_ code to point
        self.pos_to_corner[POS_M_BACK_1] = (12,75)
        self.pos_to_corner[POS_M_BACK_2] = (147,85)
        self.pos_to_corner[POS_M_BACK_3] = (282,75)
        self.pos_to_corner[POS_M_FRONT_1] = (12,190)
        self.pos_to_corner[POS_M_FRONT_2] = (147,200)
        self.pos_to_corner[POS_M_FRONT_3] = (282,190)
        self.pos_to_corner[POS_C_FRONT_1] = (12,self.screensize[1]-210)
        self.pos_to_corner[POS_C_FRONT_2] = (147,self.screensize[1]-220)
        self.pos_to_corner[POS_C_FRONT_3] = (282,self.screensize[1]-210)
        self.pos_to_corner[POS_C_BACK_1] = (12,self.screensize[1]-102)
        self.pos_to_corner[POS_C_BACK_2] = (147,self.screensize[1]-112)
        self.pos_to_corner[POS_C_BACK_3] = (282,self.screensize[1]-102)
        self.pos_to_corner[POS_DOWN] = (147,self.screensize[1]+200)
        self.pos_to_corner[POS_BACK_LEFT] = (-100,-200)
        self.pos_to_corner[POS_BACK_RIGHT] = (500,-200)
        self.pos_to_image_rect = {}
        self.pos_to_tall_image_rect = {}
        self.pos_to_health_bar_rect = {}
        self.pos_to_energy_bar_rect = {}
        for pos in self.pos_to_corner.keys():
            self.pos_to_image_rect[pos] = Rect(self.pos_to_corner[pos][0],self.pos_to_corner[pos][1],96,96)
            self.pos_to_tall_image_rect[pos] = Rect(self.pos_to_corner[pos][0],self.pos_to_corner[pos][1]-96,96,192)
            self.pos_to_health_bar_rect[pos] = Rect(self.pos_to_corner[pos][0]+101,self.pos_to_corner[pos][1],10,96)
            self.pos_to_energy_bar_rect[pos] = Rect(self.pos_to_corner[pos][0]+115,self.pos_to_corner[pos][1],10,96)
        self.pause_rect = Rect(self.pos_to_corner[POS_C_FRONT_3][0]+133,self.pos_to_corner[POS_C_FRONT_3][1]-8,60,50)
        self.flee_rect = Rect(self.pos_to_corner[POS_C_FRONT_3][0]+133,self.pos_to_corner[POS_C_FRONT_3][1]+47,60,50)
        self.quit_rect = Rect(self.pos_to_corner[POS_C_FRONT_3][0]+133,self.pos_to_corner[POS_C_FRONT_3][1]+102,60,50)
        self.restart_rect = Rect(self.pos_to_corner[POS_C_FRONT_3][0]+133,self.pos_to_corner[POS_C_FRONT_3][1]+157,60,50)
        self.action_rects = []
        for j in range(6):
            for i in range(3):
                self.action_rects.append(Rect(30+120*i,self.screensize[1]-200-120*(j+1),100,100))
        self.scrub()

    def scrub(self):
        self.message_queue = [] # 3-tuple of string, I_ code and COL_ code
        self.sound_queue = []
        self.quit_now = False
        self.quit_after_pause = False
        self.button_still_down = False
        self.started_dragging_at = 0
        self.mode = M_NORMAL
        self.actor = None
        self.action = None
        self.target = None
        self.action_choices = []
        self.message_pane.fill((0,0,0))
        self.message_pane_next_x = 5
        self.message_pane_next_y = 5
        self.top_image = None
        self.top_image_until = 0    
        self.app = gui.App()      

    def chooser_dialog(self,w,title,options):
        w.now = pygame.time.get_ticks()
        if w.resetting is False:
            w.process()
        c = gui.Container(align=-1,valign=-1)
        self.app.init(c)
        ch = Chooser(title,options)
        ch.open()
        done = False
        while not done and not ch.done:
            if android.check_pause():
                android.wait_for_resume()
            for e in pygame.event.get():
                if e.type == QUIT:
                    done = True
                elif e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
                    done = True
                else:
                    self.app.event(e)
            self.app.paint()
            pygame.display.flip()
        w.now = pygame.time.get_ticks()
        w.since_last_process = w.now       
        if ch.index_chosen is None:
            return None
        else:
            return options[ch.index_chosen]

    def container_info_dialog(self,w,title,image,content):
        w.now = pygame.time.get_ticks()
        w.process()
        c = gui.Container(align=-1,valign=-1)
        self.app.init(c)
        if image is not None:
            to_scroll = gui.Table()
            to_scroll.tr()
            to_scroll.td(gui.Image(self.big_images[image]),align=0)
            to_scroll.tr()
            to_scroll.td(content)
            to_scroll.tr()
        else:
            to_scroll = content        
        d = ContainerInfoDialog(title,to_scroll)
        d.open()
        done = False
        while not done and not d.done:
            if android.check_pause():
                android.wait_for_resume()
            for e in pygame.event.get():
                if e.type == QUIT:
                    done = True
                elif e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
                    done = True
                else:
                    self.app.event(e)
            self.app.paint()
            pygame.display.flip()
        w.now = pygame.time.get_ticks()
        w.since_last_process = w.now  
        
    def redraw(self,p,e,w):
        self.screen.blit(self.background, (0, 0))
        if self.message_pane_next_y >= 9000:
            new_message_pane = pygame.Surface([self.screensize[0]-25,10000])
            new_message_pane.blit(self.message_pane, Rect(0,0,0,0), area=Rect(0, max(0,self.message_pane_next_y-self.screensize[1]+530), self.screensize[0]-25, self.screensize[1]-527))
            self.message_pane = new_message_pane
            self.message_pane_next_y = self.screensize[1]-537
        self.screen.blit(self.message_pane, self.message_pane_at, area=Rect(0, max(0,self.message_pane_next_y-self.screensize[1]+530), self.screensize[0]-25, self.screensize[1]-527))
        stealthed = False
        invulnerable = False
        for c in p.chars:
            if c.alive and not c.about_to_die and c.current_stance==ST_STEALTH:
                stealthed = True
            if c.alive and not c.about_to_die and c.current_stance == ST_INVULNERABLE:
                invulnerable = True
        for pos in range(POS_C_FRONT_1,POS_C_BACK_3+1):
            c = p.get_char_at_pos(pos)
            if c is not None:
                if c.slide_from is None or c.slide_finish < w.elapsed_since_beginning:
                    box = self.pos_to_image_rect[pos]
                else:
                    proportion = (w.elapsed_since_beginning-c.slide_start)/(c.slide_finish-c.slide_start)
                    box = Rect(0,0,0,0)
                    for i in range(len(box)):                          
                        box[i] = (1-proportion) * self.pos_to_image_rect[c.slide_from][i] + (proportion) * self.pos_to_image_rect[c.slide_to][i]
                if stealthed:
                    self.screen.blit(self.darkened_big_images[c.image], box)
                elif invulnerable:
                    self.screen.blit(self.whiteout_big_images[c.image], box)
                elif c.has_status_effect(EF_POISON) and c.status_effects[EF_POISON].level>0:
                    self.screen.blit(self.greened_big_images[c.image], box)
                else:
                    self.screen.blit(self.big_images[c.image], box)
                colored = False
                if c.flash_image is not None:
                    if c.flash_starts is None:
                        self.screen.blit(self.big_images[c.flash_image], box)
                        colored = True
                        c.flash_starts = w.elapsed_since_beginning
                    elif w.elapsed_since_beginning >= c.flash_starts + 0.1:
                        c.flash_starts = None
                        c.flash_image = None
                    else:
                        self.screen.blit(self.big_images[c.flash_image], box)
                        colored = True
                if c.flash_number is not None:
                    if w.elapsed_since_beginning >= c.number_starts + 1.5:
                        c.flash_number = None
                        c.number_starts = None
                    else:
                        text = self.big_font.render(str(c.flash_number), False, c.number_color)
                        text.set_alpha(240 - floor(160 * (w.elapsed_since_beginning - c.number_starts)))
                        self.screen.blit(text, (box[0]+(96-text.get_width())/2,box[1]+11))                                           
                if c.about_to_die:
                    self.screen.blit(self.images[I_SKULL_CROSSBONES], (box[0] + 28,box[1] + 52))
                else:
                    if not colored and (not c.can_act() or c.has_status_effect(EF_SLEEP) or c.has_status_effect(EF_GRAPPLE)) and self.mode==M_NORMAL:
                        self.screen.blit(self.big_images[I_GREY], box)
                        colored = True
                    if self.mode==M_CHOOSE_FRIENDLY_TARGET and d.action.friend_target_ok(c):
                        self.screen.blit(self.big_images[I_GREEN_FRAME], box)
                    effects_to_show = []
                    n_effects_shown = 0
                    # no more than 11 characters please
                    if n_effects_shown<4 and c.has_status_effect(EF_RESIST_FIRE):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('FIRE RESIST')
                    if n_effects_shown<4 and c.has_status_effect(EF_RESIST_COLD):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('COLD RESIST')
                    if n_effects_shown<4 and c.has_status_effect(EF_RESIST_POISON):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('POISON RESIST')
                    if n_effects_shown<4 and c.has_status_effect(EF_PARALYSIS):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('PARALYSED')
                    if n_effects_shown<4 and c.has_status_effect(EF_SLEEP):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('ASLEEP')
                    if n_effects_shown<4 and c.has_status_effect(EF_STUN):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('STUNNED')
                    if n_effects_shown<4 and c.has_status_effect(EF_CURSE):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('CURSED')
                    if n_effects_shown<4 and c.has_status_effect(EF_FEAR):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('AFRAID')
                    if n_effects_shown<4 and c.has_status_effect(EF_GRAPPLE):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('GRAPPLED')
                    if n_effects_shown<4 and c.has_status_effect(EF_DODGE):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('DODGING')                    
                    if n_effects_shown<4 and c.has_status_effect(EF_MEDITATION):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('MEDITATING')                    
                    if n_effects_shown<4 and c.has_status_effect(EF_EV):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('WARDED')
                    if n_effects_shown<4 and c.has_status_effect(EF_SHIELD):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('SHIELDED')
                    if n_effects_shown<4 and c.has_status_effect(EF_FORCEBRAND):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('FORCE BRAND')                           
                    if n_effects_shown<4 and c.has_status_effect(EF_FRONTROWBUFF):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('BUFFED')                    
                    if n_effects_shown<4 and c.has_status_effect(EF_RIGHTEOUSNESS):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('RIGHTEOUS')                    
                    if n_effects_shown<4 and c.has_status_effect(EF_TAUNT):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('TAUNTING')                    
                    if n_effects_shown<4 and c.has_status_effect(EF_INSULT):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('INSULTING')                    
                    if n_effects_shown<4 and c.has_status_effect(EF_FIND_WEAKNESS):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('PASS ARMOR')                    
                    if n_effects_shown<4 and c.current_stance == ST_BERSERK:
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('BERSERK')
                    if n_effects_shown<4 and c.current_stance == ST_RETRENCH:
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('RETRENCHED')
                    if n_effects_shown<4 and c.current_stance == ST_ALL_OUT_DEFENSE:
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('DEFENDING')
                    if n_effects_shown<4 and c.current_stance == ST_TAKE_COVER:
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('IN COVER')
                    if n_effects_shown<4 and c.current_stance == ST_DEFLECT:
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('DEFLECT')
                    if n_effects_shown<4 and c.current_stance == ST_BLOCK:
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('BLOCK')
                    if n_effects_shown<4 and c.current_stance == ST_EPIC_BLOCK:
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('EPIC BLOCK')
                    if n_effects_shown<4 and c.current_stance == ST_LEAP_ASIDE:
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('LEAP ASIDE')
                    if n_effects_shown<4 and c.current_stance == ST_RIPOSTE:
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('RIPOSTE')
                    if n_effects_shown<4 and (c.current_stance == ST_COUNTER_PARALYSIS or c.current_stance == ST_COUNTER_FEAR or c.current_stance == ST_COUNTER_SLEEP or c.current_stance == ST_COUNTER_SILENCE or c.current_stance == ST_COUNTER_BOLTS or c.current_stance == ST_COUNTER_DEATHBLOW or c.current_stance == ST_COUNTER_MANY):
                        n_effects_shown = n_effects_shown + 1
                        effects_to_show.append('COUNTER')
                    if n_effects_shown>0:
                        text = self.small_font.render(effects_to_show[0], 1, (250,220,100))    
                        self.screen.blit(text, (box[0]+3,box[1]+80))                   
                    if n_effects_shown>1:
                        text = self.small_font.render(effects_to_show[1], 1, (250,220,100))    
                        self.screen.blit(text, (box[0]+3,box[1]+65))                   
                    if n_effects_shown>2:
                        text = self.small_font.render(effects_to_show[2], 1, (250,220,100))    
                        self.screen.blit(text, (box[0]+3,box[1]+50))                   
                    if n_effects_shown>3:
                        text = self.small_font.render(effects_to_show[3], 1, (250,220,100))    
                        self.screen.blit(text, (box[0]+3,box[1]+35))
                    if c.slide_from is None or c.slide_finish < w.elapsed_since_beginning:
                        height = c.health / float(c.max_health)
                        rect = self.pos_to_health_bar_rect[pos]
                        bar = (rect[0],rect[1]+rect[3]*(1-height),rect[2],min(self.pos_to_health_bar_rect[3],max(1,rect[3]*height)))
                        if height > 0.7:
                            pygame.draw.rect(self.screen, [20,200,20], bar)
                        elif height < 0.3:
                            pygame.draw.rect(self.screen, [200,20,20], bar)
                        else:
                            pygame.draw.rect(self.screen, [20+180*(1-((height-0.3)/0.4)),200-180*(1-((height-0.3)/0.4)),20], bar)
                        height = c.energy / float(c.max_energy)
                        rect = self.pos_to_energy_bar_rect[pos]
                        bar = (rect[0],rect[1]+rect[3]*(1-height),rect[2],min(self.pos_to_energy_bar_rect[3],max(1,rect[3]*height)))
                        if height > 0.7:
                            pygame.draw.rect(self.screen, [150,200,250], bar)
                        elif height < 0.3:
                            pygame.draw.rect(self.screen, [0,20,100], bar)
                        else:
                            pygame.draw.rect(self.screen, [150-150*(1-((height-0.3)/0.4)),200-180*(1-((height-0.3)/0.4)),250-150*(1-((height-0.3)/0.4))], bar)
            if self.mode==M_DRAGGING and w.elapsed_since_beginning>=(self.started_dragging_at+0.2) and pos<>d.actor.pos:
                if not(d.actor.front_row() and p.n_surviving_front_chars()==1 and (p.get_char_at_pos(pos) is None or p.get_char_at_pos(pos).can_act() is False) and (pos==POS_C_BACK_1 or pos==POS_C_BACK_2 or pos==POS_C_BACK_3)):
                    if not(p.get_char_at_pos(pos) is not None and p.get_char_at_pos(pos).can_act() is False):
                        self.screen.blit(self.big_images[I_BLUE_FRAME], self.pos_to_image_rect[pos])
        for pos in range(POS_M_BACK_1,POS_M_FRONT_3+1):
            m = e.get_monster_at_pos(pos)
            if m is not None:
                if m.slide_from is None or m.slide_finish < w.elapsed_since_beginning:
                    small_box = self.pos_to_image_rect[pos]
                    if m.bigtile:
                        box = self.pos_to_tall_image_rect[pos]
                    else:
                        box = self.pos_to_image_rect[pos]
                else:
                    proportion = (w.elapsed_since_beginning-m.slide_start)/(m.slide_finish-m.slide_start)
                    box = Rect(0,0,0,0)
                    small_box = Rect(0,0,0,0)
                    for i in range(len(box)):
                        small_box[i] = (1-proportion) * self.pos_to_image_rect[m.slide_from][i] + (proportion) * self.pos_to_image_rect[m.slide_to][i]
                        if not m.bigtile:
                            box[i] = (1-proportion) * self.pos_to_image_rect[m.slide_from][i] + (proportion) * self.pos_to_image_rect[m.slide_to][i]
                        else:
                            box[i] = (1-proportion) * self.pos_to_tall_image_rect[m.slide_from][i] + (proportion) * self.pos_to_tall_image_rect[m.slide_to][i]
                if not m.about_to_die:
                    if self.mode==M_CHOOSE_ENEMY_TARGET and d.action.enemy_target_ok(m):
                        self.screen.blit(self.big_images[I_RED_FRAME], small_box)
                if m.fade_in is False or m.fade_finish < w.elapsed_since_beginning:
                    mob_image = self.big_images[m.image]
                    if m.completely_invulnerable_until > w.elapsed_since_beginning:
                        if m.image==I_UNDEAD_BOSS:
                            mob_image = self.big_images[I_UNDEAD_BOSS_WHITE]
                        elif m.image==I_SORCERER:
                            mob_image = self.big_images[I_SORCERER_WHITE]
                    elif m.image==I_TURTLOID and m.invulnerable_until > w.elapsed_since_beginning:
                        mob_image = self.big_images[I_TURTLOID_INVULNERABLE]
                    self.screen.blit(mob_image, box)
                else:
                    proportion = (w.elapsed_since_beginning-m.fade_start)/(m.fade_finish-m.fade_start)
                    copy = pygame.Surface((96,96))
                    copy.blit(self.screen,Rect(0,0,0,0),box)
                    copy.set_alpha(int(floor(250*(1-proportion))))
                    self.screen.blit(self.big_images[m.image], box)
                    self.screen.blit(copy, box)
                if m.image==I_GREEN_FRAME:
                    text = self.medium_font.render(m.name, 1, (250,250,250))    
                    self.screen.blit(text, (box[0]+3,box[1]+20))                   
                colored = False
                if m.flash_image is not None:
                    if m.flash_starts is None:
                        colored = True
                        m.flash_starts = w.elapsed_since_beginning
                        if (box.height==192 and (m.flash_image == I_PALE or m.flash_image == I_VERYPALE)):
                            self.screen.blit(self.big_images[m.flash_image], box)
                            second_box = Rect(box.left,box.top+96,box.width,box.height)
                            self.screen.blit(self.big_images[m.flash_image], second_box)
                        else:
                            self.screen.blit(self.big_images[m.flash_image], small_box)
                    elif w.elapsed_since_beginning >= m.flash_starts + 0.1 and (m.flash_image==I_PALE or m.flash_image==I_VERYPALE):
                        m.flash_starts = None
                        m.flash_image = None
                    elif w.elapsed_since_beginning >= m.flash_starts + 0.4:
                        m.flash_starts = None
                        m.flash_image = None
                    else:
                        if (box.height==192 and (m.flash_image == I_PALE or m.flash_image == I_VERYPALE)):
                            self.screen.blit(self.big_images[m.flash_image], box)
                            second_box = Rect(box.left,box.top+96,box.width,box.height)
                            self.screen.blit(self.big_images[m.flash_image], second_box)
                        else:
                            self.screen.blit(self.big_images[m.flash_image], small_box)
                        colored = True
                if m.flash_number is not None and m.flash_image is None:
                    if w.elapsed_since_beginning >= m.number_starts + 1.5:
                        m.flash_number = None
                        m.number_starts = None
                    else:
                        text = self.big_font.render(str(m.flash_number), False, m.number_color)
                        text.set_alpha(240 - floor(180 * (w.elapsed_since_beginning - m.number_starts)))
                        self.screen.blit(text, (small_box[0]+(96-text.get_width())/2,small_box[1]+11))                                           
                if not colored:
                    if m.rallied_until > w.elapsed_since_beginning:
                        self.screen.blit(self.big_images[I_RED], box)
                        if box.height==192:
                            second_box = Rect(box.left,box.top+96,box.width,box.height)
                            self.screen.blit(self.big_images[I_RED], second_box)
                    if m.confused or m.stunned:
                        self.screen.blit(self.big_images[I_GREY], box)
                        if box.height==192:
                            second_box = Rect(box.left,box.top+96,box.width,box.height)
                            self.screen.blit(self.big_images[I_GREY], second_box)
                if m.about_to_die and m.flash_image is None:
                    self.screen.blit(self.images[I_SKULL_CROSSBONES], (small_box[0] + 28,small_box[1] + 52))
                if m.slide_from is None or m.slide_finish < w.elapsed_since_beginning:
                    height = m.health / float(m.max_health)
                    rect = self.pos_to_health_bar_rect[pos]
                    bar = (rect[0],rect[1]+rect[3]*(1-height),rect[2],max(1,rect[3]*height))
                    pygame.draw.rect(self.screen, [20,200,20], bar)
        if self.top_image is not None and self.top_image_until >= w.elapsed_since_beginning:
            box = self.pos_to_image_rect[POS_M_FRONT_2]
            self.screen.blit(self.big_images[self.top_image], box)
        for c in p.chars:
            if not c.alive and c.slide_from is not None and c.slide_finish >= w.elapsed_since_beginning:
                proportion = (w.elapsed_since_beginning-c.slide_start)/(c.slide_finish-c.slide_start)
                box = Rect(0,0,0,0)
                for i in range(len(box)):                          
                    box[i] = (1-proportion) * self.pos_to_image_rect[c.slide_from][i] + (proportion) * self.pos_to_image_rect[c.slide_to][i]
                self.screen.blit(self.big_images[c.image], box)
        for m in e.mobs:
            if not m.alive and m.slide_from is not None and m.slide_finish >= w.elapsed_since_beginning:
                proportion = (w.elapsed_since_beginning-m.slide_start)/(m.slide_finish-m.slide_start)
                box = Rect(0,0,0,0)
                for i in range(len(box)):
                    if m.bigtile:
                        box[i] = (1-proportion) * self.pos_to_tall_image_rect[m.slide_from][i] + (proportion) * self.pos_to_tall_image_rect[m.slide_to][i]
                    else:
                        box[i] = (1-proportion) * self.pos_to_image_rect[m.slide_from][i] + (proportion) * self.pos_to_image_rect[m.slide_to][i]
                self.screen.blit(self.big_images[m.image], box)
        for i in range(w.darkness):
            self.screen.blit(self.dim_screen, [0,0])
        self.screen.blit(self.images[I_PAUSE], self.pause_rect)
        self.screen.blit(self.images[I_FLEE], self.flee_rect)
        self.screen.blit(self.images[I_QUIT], self.quit_rect)
        self.screen.blit(self.images[I_RESTART], self.restart_rect)
        if self.grey_out: 
            self.screen.blit(self.grey_screen, [0,0])        
        elif self.mode==M_CHOOSE_ACTION:
            self.screen.blit(self.grey_screen, [0,0])
            if self.action_choices == []:
                for a in d.actor.actions:
                    if a.callable():
                        self.action_choices.append(a)
            count = 0
            for action in self.action_choices:
                if action.limited_uses==0:
                    count = count + 1
                    continue
                if action.ok():
                    fill_color = [255,255,255]
                    line_color = [0,0,0]
                else:
                    fill_color = [120,120,120]
                    line_color = [80,80,80]
                pygame.draw.rect(self.screen,fill_color,self.action_rects[count],0)
                pygame.draw.rect(self.screen,line_color,self.action_rects[count],1)
                if action.cooldown() is not None and action.last_used is not None:
                    if (action.last_used+action.cooldown()>w.elapsed_since_beginning):
                        cooldown_prop = 1-(w.elapsed_since_beginning-action.last_used)/action.cooldown()
                        cooldown_rect = Rect(self.action_rects[count].left+5,self.action_rects[count].top+5,cooldown_prop*(self.action_rects[count].width-10),5)
                        pygame.draw.rect(self.screen,[210,50,50],cooldown_rect,0)
                full_text = action.name();
                if action.limited_uses is not None:
                    if action.limited_uses > 1:
                        full_text = full_text + ' (x' + str(action.limited_uses) + ')'
                line1 = full_text;
                line2 = '';
                line3 = '';
                if len(full_text)>8:
                    for i in range(4,len(full_text)):
                        if full_text[i]==' ':
                            line1 = full_text[0:i]
                            full_text = full_text[(i+1):len(full_text)]
                            line2 = full_text
                            break
                if len(full_text)>8:
                    for i in range(4,len(full_text)):
                        if full_text[i]==' ':
                            line2 = full_text[0:i]
                            line3 = full_text[(i+1):len(full_text)]
                            break
                if line2=='':
                    text = self.font.render(line1, 1, line_color)
                    self.screen.blit(text, (self.action_rects[count][0]+(100-text.get_width())/2,self.action_rects[count][1]+35))
                elif line3=='':
                    text = self.font.render(line1, 1, line_color)
                    self.screen.blit(text, (self.action_rects[count][0]+(100-text.get_width())/2,self.action_rects[count][1]+25))
                    text = self.font.render(line2, 1, line_color)
                    self.screen.blit(text, (self.action_rects[count][0]+(100-text.get_width())/2,self.action_rects[count][1]+50))
                else:
                    text = self.font.render(line1, 1, line_color)
                    self.screen.blit(text, (self.action_rects[count][0]+(100-text.get_width())/2,self.action_rects[count][1]+10))
                    text = self.font.render(line2, 1, line_color)
                    self.screen.blit(text, (self.action_rects[count][0]+(100-text.get_width())/2,self.action_rects[count][1]+35))
                    text = self.font.render(line3, 1, line_color)
                    self.screen.blit(text, (self.action_rects[count][0]+(100-text.get_width())/2,self.action_rects[count][1]+60))
                count = count + 1
        elif w.slow_time_until >= w.elapsed_since_beginning:
            self.screen.blit(self.blue_screen, [0,0])
        pygame.display.flip()

    def print_message(self,a,image,color):
        size = self.font.size(a)
        text = self.font.render(a, 1, color)
        if image is None:
            self.message_pane.blit(text, (self.message_pane_next_x,self.message_pane_next_y))
            self.message_pane_next_y = self.message_pane_next_y + 25
        else:
            if self.small_images[image].get_height()==40:
                self.message_pane.blit(self.small_images[image],(self.message_pane_next_x,self.message_pane_next_y)) 
                self.message_pane.blit(text, (self.message_pane_next_x+54,self.message_pane_next_y+5))
                self.message_pane_next_y = self.message_pane_next_y + 43
            else:
                self.message_pane_next_y = self.message_pane_next_y - 20
                self.message_pane.blit(self.small_images[image],(self.message_pane_next_x,self.message_pane_next_y)) 
                self.message_pane.blit(text, (self.message_pane_next_x+54,self.message_pane_next_y+39))
                self.message_pane_next_y = self.message_pane_next_y + 83
        self.message_pane_next_x = 5

    def make_singlecolor_overlay(self,color,alpha):
        overlay = pygame.Surface((96,96))
        overlay.fill(color)
        overlay.set_alpha(alpha)
        return overlay

    def get_click(self):
        for event in pygame.event.get():
            if event.type == QUIT:
                return -1
            if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                return -1
            if event.type == pygame.MOUSEBUTTONUP:
                if self.button_still_down == False:
                    return None
                else:
                    self.button_still_down = False
                    return event.pos
            if event.type == pygame.MOUSEBUTTONDOWN:
                if self.button_still_down == True:
                    return None
                else:
                    self.button_still_down = True
                    return event.pos
        return None

    def get_mouse_pos(self):
        return pygame.mouse.get_pos()

    def log(self,text):
        self.logfile.write(text + '\n')
      
d = Display()
